// src/utils/useFetchLogicHook.ts
import { useState, useEffect, useCallback, useRef } from 'react';
import { debounce } from './debounce';
import { fetchCharacter } from '../service/apiService';
import { Character } from '../models/types';

export const useFetchLogicHook = (): [
    string,
    Character[],
    number,
    number,
    string,
    boolean,
    (event: React.ChangeEvent<HTMLInputElement>) => void,
    () => void,
    () => void
] => {
    const [name, setName] = useState('');
    const [characters, setCharacters] = useState<Character[]>([]);
    const [page, setPage] = useState(1);
    const [totalPages, setTotalPages] = useState(1);
    const [error, setError] = useState('');
    const [isLoading, setIsLoading] = useState(false);
    let controller = useRef<AbortController | null>(null);

    const debouncedFetchCharacter = useCallback(
        debounce((name: string, page: number) => {
            if(controller.current) {
                controller.current.abort()
            }
            controller.current = new AbortController()
            const signal = controller.current.signal;

            setIsLoading(true);
            setError('');
            fetchCharacter(name, page, { signal })
                .then((data) => {
                    setCharacters(data.results);
                    setTotalPages(data.info.pages);
                    setIsLoading(false);
                })
                .catch((error) => {
                    setError(error.message);
                    setIsLoading(false);
                    setCharacters([]);
                });
        }, 500),
        []
    );

    useEffect(() => {
        if (name.trim()) {
            debouncedFetchCharacter(name, page);
        } else {
            setIsLoading(false);
            setCharacters([]);
            setError('');
        }
    }, [name, page, debouncedFetchCharacter]);

    const handleNameChange = (event: React.ChangeEvent<HTMLInputElement>) => {
        setName(event.target.value);
    };

    const handleNextPage = () => {
        setPage((prevPage) => Math.min(prevPage + 1, totalPages));
    };

    const handlePreviousPage = () => {
        setPage((prevPage) => Math.max(prevPage - 1, 1));
    };

    return [
        name,
        characters,
        page,
        totalPages,
        error,
        isLoading,
        handleNameChange,
        handleNextPage,
        handlePreviousPage
    ];
};
